#include "../../common/etcder.hpp"
#include "../../common/channel.hpp"
#include "main.pb.h"
#include <gflags/gflags.h>
#include <brpc/channel.h>
#include <functional>
#include <iostream>

DEFINE_bool(log_mode, false, "程序的运行模式: true-发布模式 false-调试模式");
DEFINE_string(log_file, "", "发布模式下，制定日志的输出文件");
DEFINE_int32(log_level, 0, "发布模式下，制定日志的输出等级");

DEFINE_string(etcd_host, "127.0.0.1:2379", "服务注册中心地址");
DEFINE_string(service_dir, "/service", "服务监测根目录");

DEFINE_string(service, "/service/echo", "服务名称");

void online(const std::string &service_name, const std::string &service_host)
{
    LOG_INFO("服务[{}]-[{}]上线", service_name, service_host);
}
void offline(const std::string &service_name, const std::string &service_host)
{
    LOG_INFO("服务[{}]-[{}]下线", service_name, service_host);
}
int main(int argc, char *argv[])
{
    google::ParseCommandLineFlags(&argc, &argv, true);
    initLogger(FLAGS_log_mode, FLAGS_log_file, FLAGS_log_level);

    // 构造Rpc服务管理对象
    auto manager = std::make_shared<zhong::servicer::ServiceManager>();
    manager->declareService(FLAGS_service);
    // 构造服务发现对象
    auto put_cb = std::bind(&zhong::servicer::ServiceManager::onServiceOnline, manager.get(),
                            std::placeholders::_1, std::placeholders::_2);
    auto del_cb = std::bind(&zhong::servicer::ServiceManager::onServiceOffLine, manager.get(),
                            std::placeholders::_1, std::placeholders::_2);
    auto discoverer = std::make_shared<zhong::etcder::Discovery>(FLAGS_service_dir, FLAGS_etcd_host, put_cb, del_cb);
    while (1)
    {
        // 获取服务信道
        auto channel = manager->choose(FLAGS_service);
        if (channel.get() == nullptr)
        {
            return -1;
        }
        // 进行Rpc调用
        // EchoService服务存根
        auto stub = std::make_shared<example::EchoService_Stub>(channel.get());
        // 进行rpc调用
        auto req = std::make_shared<example::EchoRequest>();
        req->set_message("this is a test");
        auto resp = std::make_shared<example::EchoResponse>();
        // 获取一个rpc操作对象
        auto cntl = std::make_shared<brpc::Controller>(); // ??
        // 同步
        stub->Echo(cntl.get(), req.get(), resp.get(), nullptr);
        if (cntl->Failed() == true)
        {
            std::cout << "Rpc调用失败：" << cntl->ErrorText() << std::endl;
            std::this_thread::sleep_for(std::chrono::seconds(1));
            continue;
        }
        // 通过stub服务存根获取到响应
        std::cout << "收到响应# " << resp->message() << std::endl; // 这里为同步！！！
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}